package com.youku.mson.type;

import java.lang.reflect.Array;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

import com.youku.mson.util.TypeAdapter;

public class ArrayJsonValue implements JsonValue {

	private List<JsonValue> elements;

	public ArrayJsonValue(List<JsonValue> elements) {
		this.elements = elements;
	}

	@Override
	public Object read(TypeAdapter adapter) {
		if (adapter.getTargetClass().isArray()) {
			return createArray(adapter);
		} else {
			return createList(adapter);
		}
	}

	private List<Object> createList(TypeAdapter adapter) {
		Type type = adapter.getType();

		Class<?> elementClass = null;
		if (type instanceof ParameterizedType) {
			ParameterizedType pt = (ParameterizedType) type;
			elementClass = (Class<?>) pt.getActualTypeArguments()[0];
		} else {
			elementClass = Object.class;
		}

		TypeAdapter apt = new TypeAdapter(elementClass);
		List<Object> array = new ArrayList<>(elements.size());
		for (JsonValue element : elements) {
			array.add(element.read(apt));
		}

		return array;
	}

	private Object createArray(TypeAdapter adapter) {
		Class<?> componentType = adapter.getTargetClass().getComponentType();
		Object array = Array.newInstance(componentType, elements.size());

		for (int i = 0; i < elements.size(); i++) {
			JsonValue element = elements.get(i);
			Array.set(array, i, element.read(new TypeAdapter(componentType)));
		}

		return array;
	}

}
